import {
    evaluate
  } from 'mathjs'

/* eslint-disable no-useless-escape */
// 求逆波兰表达式的值
function evalRPN(tokens) {
    const operation = {
        '+': (a, b) => a + b,
        '-': (a, b) => a - b,
        '*': (a, b) => a * b,
        '/': (a, b) => {
            if (b < 0) {
                return 0;
            }
            // eslint-disable-next-line radix
            return parseInt(a / b);
        },
    };
    const stack = [];
    for (let i = 0; i < tokens.length; i++) {
        if (tokens[i] in operation) {
            if (stack.length >= 2) {
                const b = Number(stack.pop());
                const a = Number(stack.pop());
                const result = operation[tokens[i]](a, b);
                stack.push(result);
            } else {
                return 0;
            }
        } else {
            stack.push(tokens[i]);
        }
    }
    return stack.pop();
}

/*
 * 假如待选变量：  ID,NUM,TOTAL，AVL TEST
 * 正确的公式例子：ID*NUM+(TOTAL/AVL)*0.5
 * 错误的公式例子：ID**|0.5
 */
function fn(string) {
    // TODO: 如何处理=？
    // 剔除空白符
    const newString = string.replace(/\s/g, '');
    // 错误情况，空字符串
    if (newString === '') {
        return false;
    }

    // 错误情况，变量没有来自“待选公式变量”
    const tmpStr = newString.replace(/[\(\)\+\-\*\/]{1,}/g, '`');
    const array = tmpStr.split('`');
    for (let i = 0; i < array.length; i++) {
        // 得到了输入的值
        const item = array[i];
        if (item.search("%") === -1) {
            return "变量没有来自“待选公式变量";
        }
    }

    // 错误情况，运算符连续
    // if (/[\+\-\*\/]{2,}/.test(newString)) {
    //     return false;
    // }

    // 空括号
    if (/\(\)/.test(newString)) {
        return "表达式不允许为空括号";
    }

    // 错误情况，括号不配对
    const stack = [];
    for (let i = 0; i < newString.length; i++) {
        const item = newString.charAt(i);
        if (item === '(') {
            stack.push('(');
        } else if (item === ')') {
            if (stack.length > 0) {
                stack.pop();
            } else {
                return "括号不匹配";
            }
        }
    }
    if (stack.length !== 0) {
        return false;
    }

    // 错误情况，(后面是运算符
    if (/\([\+\-\*\/]/.test(newString)) {
        return "(后面是运算符";
    }

    // 错误情况，)前面是运算符
    if (/[\+\-\*\/]\)/.test(newString)) {
        return ")前面是运算符";
    }
    // 错误情况，(前面不是运算符
    if (/[^\+\-\*\/\%]\(/.test(newString)) {
        return "(前面不是运算符";
    }

    // 错误情况，)后面不是运算符
    if (/\)[^\+\-\*\/\%]/.test(newString)) {
        return ")后面不是运算符";
    }
    // 错误情况，使用除()+-*/%之外的字符
    if (/[^\+\-\*\/0-9.a-zA-Z\(\)\%]/.test(newString)) {
        return "使用除()+-*/%之外的字符";
    }
    // 除了-号运算符号不能在首末位
    if (/^[\+\*\/.]|[\+\-\*\/.]$/.test(newString)) {
        return "除了-号运算符号不能在首末位";
    }
    // 错误情况运算符结尾
    if (/[\+\-\*\/]$/.test(newString)) {
        return " 错误情况运算符结尾";
    }

    return "公式成立";
}



// 将普通算数表达式即中缀表达式转换为逆波兰表达式即后缀表达式
function rp(str) {
    const ops = "+-#*/".split(""); // #用来分级，+-是同一级，*/同一级，两级之间的位置差至少为2
    const result = [];
    const temp = [];
    const infixArr = str.split('%');
    infixArr.forEach((item, i) => {
        if (item === "加") {
            infixArr[i] = '+'
        } else if (item === "减") {
            infixArr[i] = '-'
        } else if (item === "乘") {
            infixArr[i] = '*'
        } else if (item === "除") {
            infixArr[i] = '/'
        } else if (item === "左括号") {
            infixArr[i] = '('
        } else if (item === "右括号") {
            infixArr[i] = ')'
        }
    })
    // 去除空格
    infixArr.forEach((item, i) => {
        if (item === '') {
            infixArr.splice(i, 1);
        }
    })
    console.log(infixArr);
    infixArr.forEach(ele => {
        if (ele === "(") {
            temp.push(ele); // 左括号直接推入暂存区
        } else if (ele === ")") {
            let flag = true;
            while (flag) {
                if (temp[temp.length - 1] !== "(") {
                    result.push(temp.pop());
                } else {
                    temp.pop();
                    flag = false;
                }
            }
        } else if (ops.indexOf(ele) !== -1) {
            // eslint-disable-next-line no-inner-declarations
            function cb(x, o) {
                if (
                    o.length === 0 ||
                    o[o.length - 1] === "(" ||
                    ops.indexOf(x) - ops.indexOf(o[o.length - 1]) > 2
                ) {
                    // 判断分级
                    o.push(x);
                } else {
                    result.push(o.pop());
                    return cb(x, o);
                }
                return null;
            }
            cb(ele, temp);
        } else {
            result.push(ele);
        }
    });
    while (temp.length > 0) {
        if (temp[temp.length - 1] !== "(") {
            result.push(temp.pop());
        } else {
            temp.pop();
        }
    }
    return result;
}

// 使用
export default function mathematicsUtils(formula, fields) {
    // 获取字符串并把中文替换成变量
    let newString = formula;
    newString = newString.replace(new RegExp(/\d+/, 'ig'), (a1) => `%${a1}%`);
    newString = newString.replace(new RegExp(/(\-|\+)?\d+(\.\d+)?/,'ig'), (a1) =>{
        return `%${a1}%`;
    });
    Object.keys(fields).forEach(item => {
        newString = newString.replace(new RegExp(item, 'ig'), `%${fields[item]}%`);
    });
    newString = newString.replace(new RegExp(/\(/, 'ig'), "%(");
    newString = newString.replace(new RegExp(/\)/, 'ig'), ")%");

    // math库
    Object.keys(fields).forEach(item => {
        newString = newString.replace(new RegExp(item, 'ig'), fields[item]);
    });

    /*
    * eval 是有害的暂不考虑
    */
    // console.log(eval(newString));
    // Object.keys(fields).forEach(item => {
    //     newString = newString.replace(new RegExp(item, 'ig'), fields[item]);
    // });

    // 提交到服务器端的字符串不应该包含空白符，或者应该禁止用户输入空白符
    if (fn(newString) !== "公式成立") {
        return fn(newString);
    }
    return evaluate(newString);
}
